package main

import (
	"fmt"
	"unsafe"
)

//数组类型——Go语言内置类型
//数组定义: var arr [N]T
//两个属性: 数组长度N 元素类型T
//数组可以通过下标进行高效访问
//Go语言中,数组变量表示的是整个数组,在数组传参时采用的是纯粹的值拷贝,这会造成较大的内存拷贝开销
//数组的缺点: 1.完全的值拷贝,性能开销较大 2.长度固定,不支持扩容

func main() {
	//printArray()

	declareArray()

	//traverseArray()
}

// 打印数组
func printArray() {
	arr := []int{1, 2, 3, 4, 5, 6}
	fmt.Printf("数组长度len: %d\n", len(arr))              //6
	fmt.Printf("数组容量cap: %d\n", cap(arr))              //6
	fmt.Printf("数组类型type: %T\n", arr)                  //[]int
	fmt.Printf("数组占用内存空间大小: %d\n", unsafe.Sizeof(arr)) //6*8=48
}

// 声明数组
// 声明数组时,必须指定长度,Go编译器需要在编译阶段就确定数组类型的长度
func declareArray() {
	//声明数组并显式初始化
	arr1 := [3]int{1, 2, 3}
	//可以通过len获取数组长度,cap获取数组容量
	fmt.Printf("arr1: %v\tlen: %d\tcap:%d\n", arr1, len(arr1), cap(arr1))

	//数组实际元素的数量可以少于len,但是不能多,未赋值的元素会被赋予零值
	arr2 := [4]int{1, 2, 3} //{1,2,3,0}
	fmt.Printf("arr2: %v\tlen: %d\tcap:%d\n", arr2, len(arr2), cap(arr2))

	//声明数组时,如果不显式初始化,那么所有元素会被自动赋予零值
	var arr3 [4]int //{0,0,0,0}
	fmt.Printf("arr3: %v\tlen: %d\tcap:%d\n", arr3, len(arr3), cap(arr3))

	//声明数组时可以省略数组长度,用'...'代替,编译器会自动根据元素数量计算长度
	arr4 := [...]int{1, 2, 3, 4, 5}
	fmt.Printf("arr4: %v\tlen: %d\tcap:%d\n", arr4, len(arr4), cap(arr4))

	//通过下标赋值,显式初始化,适用于稀疏数组
	arr5 := [...]int{
		8: 9,
		9: 10,
	}
	fmt.Printf("arr5: %v\tlen: %d\tcap:%d\n", arr5, len(arr5), cap(arr5))
}

// 遍历数组
func traverseArray() {
	//通过for-range方式遍历数组
	arr := [...]int{1, 2, 3, 4, 5}

	for i, v := range arr {
		fmt.Printf("idx: %d, value: %d\n", i, v)
	}
}
